package com.hqd.jjvm.rtda.heap;

import com.hqd.jjvm.classformat.FieldInfo;
import com.hqd.jjvm.classformat.attributeinfo.AttributeInfo;
import com.hqd.jjvm.classformat.attributeinfo.ConstantValue;
import com.hqd.jjvm.classformat.constantpool.ConstantPool;
import com.hqd.jjvm.rtda.slot.NumberSlot;
import com.hqd.jjvm.rtda.slot.RefSlot;
import com.hqd.jjvm.rtda.slot.Slot;
import com.hqd.jjvm.util.ClassUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class JField extends JClassMember {
    /**
     * 顺序标号
     */
    private Integer slotId;
    /**
     * 常量池引用
     */
    private Integer constantIndex;
    /**
     * 初始化值
     */
    private Slot value;

    public JField(FieldInfo fieldInfo, JClass jClass, List<ConstantPool> constantPools) {
        createJField(fieldInfo, jClass, constantPools);
    }


    public void initDefaultVal(JClass jClass, Integer index) {

        Object val = null;
        Class clazz = ClassUtil.getClassByDescriptor(getDescriptor());
        if (index != null) {
            val = jClass.getConstantPool().getConstantVal(index);
        } else {
            if (ClassUtil.isPrimitive(clazz)) {
                val = 0;
            }
        }
        if (ClassUtil.isPrimitive(clazz)) {
            value = new NumberSlot(0);
        } else {
            value = new RefSlot();
        }
    }

    @Override
    protected void newDescInfo(AttributeInfo attr, JClass jClass, List<ConstantPool> constantPool) {
        /**
         * 存在值，则进行赋值操作
         * 不存在则赋默认值
         */
        if (attr instanceof ConstantValue) {
            this.setConstantIndex(((ConstantValue) attr).getConstantValueIndex());
        }
    }

    private void createJField(FieldInfo fieldInfo, JClass jClass, List<ConstantPool> constantPool) {
        super.newJClassMember(fieldInfo, jClass, constantPool);
        if (this.isStatic()) {
            this.initDefaultVal(jClass, constantIndex);
        }
    }
}
